package medOffice;
import java.util.Calendar;
import java.util.GregorianCalendar;

import medOffice.Enuns.Sexo;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * Testes da classe Pessoa.
 * @author Amilton 
 *
 */
public class TestesPessoa {

	Pessoa p1, p2;
	
	public class PessoaConcreta extends Pessoa {

		public PessoaConcreta(String nome, String cpf) throws Exception {
			super(nome, cpf);
		}
	}
	
	@Before
	public void setUp() throws Exception {
		p1 = new PessoaConcreta("Joao Maria", "123456789-00");
		p2 = new PessoaConcreta("Maria Joao", "000000000-00");
	}
	
	/*
	 * Testa a validade da formatacao do nome.
	 */
	@Test(expected = Exception.class)
	public void testNomePessoaNull() throws Exception {
		Pessoa p = new PessoaConcreta(null, "123123123-00");
	}
	
	@Test(expected = Exception.class)
	public void testNomePessoaVazio() throws Exception {
		Pessoa p = new PessoaConcreta("", "123123123-00");
	}
	
	@Test(expected = Exception.class)
	public void testNomePessoaComDigito() throws Exception {
		Pessoa p = new PessoaConcreta("Jo40 M4ria", "123123123-00");
	}
	
	@Test(expected = Exception.class)
	public void testNomePessoaInvalido1() throws Exception {
		Pessoa p = new PessoaConcreta("Joao Maria212212", "123123123-00");
	}
	
	@Test(expected = Exception.class)
	public void testNomePessoaInvalido2() throws Exception {
		Pessoa p = new PessoaConcreta("Joao111 Maria", "123123123-00");
	}
	
	@Test(expected = Exception.class)
	public void testCpfInvalido() throws Exception {
		Pessoa p = new PessoaConcreta("Ana", null);
	}
	
	@Test(expected = Exception.class)
	public void testCpfVazio() throws Exception {
		Pessoa p = new PessoaConcreta("Ana", "");
	}
	
	/*
	 * Testa os geters e seters
	 */
	@Test
	public void testGetNome() {
		Assert.assertEquals("Nome da pessoa 1 incorreto.", "Joao Maria", p1
				.getNome());
		Assert.assertEquals("Nome da pessoa 2 incorreto.", "Maria Joao", p2
				.getNome());
	}
	
	@Test (expected = Exception.class)
	public void testSetCPFNull() throws Exception{
		p1.setCPF(null);
	}
	
	@Test (expected = Exception.class)
	public void testSetCPFVazio() throws Exception{
		p1.setCPF("");
	}
	
	@Test (expected = Exception.class)
	public void testSetCPFSemDigito() throws Exception{
		p1.setCPF("00000000000");
	}
	
	@Test (expected = Exception.class)
	public void testSetCPFComLetras() throws Exception {
		p1.setCPF("000000000a00");
	}
	
	@Test (expected = Exception.class)
	public void testSetCPFComDigitos() throws Exception {
		p1.setCPF("00000.000-00");
	}
	
	@Test (expected = Exception.class)
	public void testSetCPFMenor() throws Exception {
		p1.setCPF("12345678-00");
	}
	
	@Test
	public void testSetCPF() throws Exception {
		p1.setCPF("123456789-00");
		Assert.assertEquals("CPF errado", "123456789-00", p1.getCPF());
	}
	
	@Test
	public void testGetCPF() throws Exception{
		p1.setCPF("123456789-00");
		Assert.assertEquals("Numero do CPF errado", p1.getCPF(), "123456789-00");
	}

	@Test
	public void testSetEndereco(){
		try {
			p1.setEndereco(null);
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Endereço invalido", e.getMessage());
		}
		
		try {
			p1.setEndereco("R. Rua tal, 123 Bairro");
			p1.setEndereco("R. Rua tal, nao digito, Bairro");
			p1.setEndereco("R. Ru4 tal, 123, 123");
			p1.setEndereco("R. Rua tal 123 Bairro");
			p1.setEndereco("R Qualquer Coisa, 123, Bairro");
		} catch (Exception e) {
			Assert.fail("Nao deveria ter mensagem de erro");
		}
		
	}
	
	@Test
	public void testGetEndereco() throws Exception{
		p1.setEndereco("R. Qualquer Coisa, 123, Bairro");
		Assert.assertEquals("Endereco errado", p1.getEndereco(), "R. "
				+ "Qualquer Coisa, 123, Bairro");
	}
	
	@Test
	public void testSetTelefone() throws Exception{
		try {
			p1.setTelefone(null);
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Telefone invalido", e.getMessage());
		}
		try {
			p1.setTelefone("(0) 1234-1234");
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Telefone invalido", e.getMessage());
		}
		try {
			p1.setTelefone("(00 1234-1234");
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Telefone invalido", e.getMessage());
		}
		try {
			p1.setTelefone("00 1234-1234");
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Telefone invalido", e.getMessage());
		}
		try {
			p1.setTelefone("(a0) 1234-1234");
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Telefone invalido", e.getMessage());
		}
		try {
			p1.setTelefone("(00) a123-1234");
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Telefone invalido", e.getMessage());
		}
		try {
			p1.setTelefone("(00) 123-1234");
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Telefone invalido", e.getMessage());
		}
		try {
			p1.setTelefone("(00) 1234 1234");
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Telefone invalido", e.getMessage());
		}
		try {
			p1.setTelefone("(00) 1234-123A");
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Telefone invalido", e.getMessage());
		}
		try {
			p1.setTelefone("(00) 1234-123");
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Telefone invalido", e.getMessage());
		}
		try {
			p1.setTelefone("(00) a123-12345");
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Telefone invalido", e.getMessage());
		}
		p1.setTelefone("(83) 3333-3333");
	}
	
	@Test
	public void testGetTelefone() throws Exception{
		p1.setTelefone("(83) 3333-3333");
		Assert.assertEquals("Numero de telefone errado", "(83) 3333-3333", 
				p1.getTelefone());
	}
	
	@Test
	public void testSetDataDeNascimento() throws Exception{
		try {
			p1.setDataDeNascimento(new GregorianCalendar());
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Data de nascimento invalida", e.getMessage());
		}
		try {
			p1.setDataDeNascimento(new GregorianCalendar(2010, 4, 3));
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Data de nascimento invalida", e.getMessage());
		}
		try {
			p1.setDataDeNascimento(new GregorianCalendar(2009, 11, 12));
		} catch (Exception e) {
			Assert.assertEquals("Mensagem de erro errada", "Data de nascimento invalida", e.getMessage());
		}
		p1.setDataDeNascimento(new GregorianCalendar(1991, 3, 13));
	}
	
	@Test
	public void testGetDataDeNascimento() throws Exception{
		p1.setDataDeNascimento(new GregorianCalendar(1991, 3, 13));
		Assert.assertEquals("Data errada", p1.getDataDeNascimento(),
				new GregorianCalendar(1991, 3, 13));
	}
	
	@Test
	public void testGetIdade() throws Exception{
		int idade;
		p1.setDataDeNascimento(new GregorianCalendar(1991, 3, 13));
		Calendar nascimento = p1.getDataDeNascimento();
		Calendar dataAtual = new GregorianCalendar();
		
		if (nascimento.get(Calendar.MONTH) < dataAtual.get(Calendar.MONTH))
			idade = dataAtual.get(Calendar.YEAR) - nascimento.get(Calendar.YEAR);
		else if (nascimento.get(Calendar.MONTH) == dataAtual.get(Calendar.MONTH) &&
			(nascimento.get(Calendar.DAY_OF_MONTH) <= dataAtual.get(Calendar.DAY_OF_MONTH)))
			idade = dataAtual.get(Calendar.YEAR) - nascimento.get(Calendar.YEAR);
		else{
			idade = dataAtual.get(Calendar.YEAR) - nascimento.get(Calendar.YEAR) - 1;
		}
		
		Assert.assertEquals("Calculo da idade errado", idade, p1.getIdade());
	}
	
	@Test (expected = Exception.class)
	public void testSetEmail1() throws Exception{
		p1.setEmail(null);
	}
	
	@Test (expected = Exception.class)
	public void testSetEmail3() throws Exception{
		p1.setEmail("abc@em4il.com");
	}
	
	@Test (expected = Exception.class)
	public void testSetEmail4() throws Exception{
		p1.setEmail("abc@email");
	}
	
	@Test (expected = Exception.class)
	public void testSetEmail5() throws Exception{
		p1.setEmail("@email.com");
	}
	
	@Test (expected = Exception.class)
	public void testSetEmail6() throws Exception{
		p1.setEmail("abcemail.com");
	}
	
	@Test (expected = Exception.class)
	public void testSetEmail7() throws Exception{
		p1.setEmail("abc@email.c0m");
	}
	
	@Test (expected = Exception.class)
	public void testSetEmail8() throws Exception{
		p1.setEmail("abc@.c0m");
	}
	
	@Test (expected = Exception.class)
	public void testSetEmail9() throws Exception{
		p1.setEmail("abc@email.com.b2");
	}

	@Test
	public void testSetEmail() throws Exception{
		p1.setEmail("abc1@email.com.br");
		p2.setEmail("maria@email.com");
		Assert.assertEquals("Email p1 errado", p1.getEmail(), "abc1@email.com.br");
		Assert.assertEquals("Email p2 errado", p2.getEmail(), "maria@email.com");
	}
	
	@Test
	public void testGetEmail() throws Exception{
		p1.setEmail("abc@email.com.br");
		p2.setEmail("maria@email.com");
		Assert.assertEquals("Email errado", "abc@email.com.br", p1.getEmail());
		Assert.assertEquals("Email errado", "maria@email.com", p2.getEmail());
	}
	
	@Test
	public void testSexo() throws Exception{
		p1.setSexo(Sexo.F);
		p2.setSexo(Sexo.M);
		Assert.assertNotSame("Sexo errado", p2.getSexo(), p1.getSexo());
		p2.setSexo(Sexo.F);
		Assert.assertEquals("Sexo errado", p2.getSexo(), p1.getSexo());
		
	}
	
	@Test
	public void testToString() throws Exception {
		p1.setCPF("123456789-00");
		Assert.assertTrue("toString errado!", "Nome: Joao Maria\nCPF: 123456789-00"
				.equals(p1.toString()));
	}

	@Test
	public void testEquals() throws Exception {
		Pessoa p3 = new Pessoa("Qualquer nome", "123123123-00");
		p1.setCPF("123456789-00");
		p3.setCPF("123456789-00");
		Assert.assertTrue("Deveriam ser iguais", p3.equals(p1));
	}
	
}